/**
 * @p.md
 * 
 * SystemMessages 模块，定义 Actor 系统内部通信的消息类型
 */
import { PID } from './pid';

/**
 * 系统消息基类
 */
export interface SystemMessage {
  /**
   * 消息类型标识
   */
  type: string;
}

/**
 * 启动消息 - 通知 Actor 启动
 */
export class Started implements SystemMessage {
  public readonly type: string = 'Started';
}

/**
 * 停止消息 - 通知 Actor 停止
 */
export class Stop implements SystemMessage {
  public readonly type: string = 'Stop';
}

/**
 * 重启消息 - 通知 Actor 重启
 */
export class Restart implements SystemMessage {
  public readonly type: string = 'Restart';

  /**
   * 构造重启消息
   * @param reason 重启原因
   */
  constructor(public readonly reason: Error) {}
}

/**
 * 终止消息 - 通知 Actor 立即终止
 */
export class Terminated implements SystemMessage {
  public readonly type: string = 'Terminated';

  /**
   * 构造终止消息
   * @param who 被终止的 Actor PID
   */
  constructor(public readonly who: PID) {}
}

/**
 * 监视消息 - 请求监视指定的 Actor
 */
export class Watch implements SystemMessage {
  public readonly type: string = 'Watch';

  /**
   * 构造监视消息
   * @param watcher 监视者 PID
   */
  constructor(public readonly watcher: PID) {}
}

/**
 * 取消监视消息 - 请求取消监视指定的 Actor
 */
export class Unwatch implements SystemMessage {
  public readonly type: string = 'Unwatch';

  /**
   * 构造取消监视消息
   * @param watcher 监视者 PID
   */
  constructor(public readonly watcher: PID) {}
}

/**
 * 失败消息 - 通知 Actor 子级失败
 */
export class Failure implements SystemMessage {
  public readonly type: string = 'Failure';

  /**
   * 构造失败消息
   * @param who 失败的 Actor PID
   * @param reason 失败原因
   */
  constructor(
    public readonly who: PID,
    public readonly reason: Error
  ) {}
}

/**
 * 恢复消息 - 通知 Actor 恢复处理
 */
export class Resume implements SystemMessage {
  public readonly type: string = 'Resume';

  /**
   * 构造恢复消息
   * @param reason 恢复原因
   */
  constructor(public readonly reason: Error) {}
}

/**
 * 接收超时消息 - 通知 Actor 接收超时
 */
export class ReceiveTimeout implements SystemMessage {
  public readonly type: string = 'ReceiveTimeout';
}

/**
 * 毒丸消息 - 通知 Actor 平滑停止
 */
export class PoisonPill implements SystemMessage {
  public readonly type: string = 'PoisonPill';
}

/**
 * 检查系统消息类型
 * @param message 待检查的消息
 * @returns 是否为系统消息
 */
export function isSystemMessage(message: any): message is SystemMessage {
  return message &&
    typeof message === 'object' &&
    'type' in message &&
    [
      'Started', 'Stop', 'Restart', 'Terminated',
      'Watch', 'Unwatch', 'Failure', 'Resume',
      'ReceiveTimeout', 'PoisonPill'
    ].includes(message.type);
}

/**
 * 系统消息工厂，提供创建系统消息的方法
 */
export const SystemMessages = {
  /**
   * 创建启动消息
   */
  started(): Started {
    return new Started();
  },
  
  /**
   * 创建停止消息
   */
  stop(): Stop {
    return new Stop();
  },
  
  /**
   * 创建重启消息
   * @param reason 重启原因
   */
  restart(reason: Error): Restart {
    return new Restart(reason);
  },
  
  /**
   * 创建终止消息
   * @param who 被终止的 Actor PID
   */
  terminated(who: PID): Terminated {
    return new Terminated(who);
  },
  
  /**
   * 创建监视消息
   * @param watcher 监视者 PID
   */
  watch(watcher: PID): Watch {
    return new Watch(watcher);
  },
  
  /**
   * 创建取消监视消息
   * @param watcher 监视者 PID
   */
  unwatch(watcher: PID): Unwatch {
    return new Unwatch(watcher);
  },
  
  /**
   * 创建失败消息
   * @param who 失败的 Actor PID
   * @param reason 失败原因
   */
  failure(who: PID, reason: Error): Failure {
    return new Failure(who, reason);
  },
  
  /**
   * 创建恢复消息
   * @param reason 恢复原因
   */
  resume(reason: Error): Resume {
    return new Resume(reason);
  },
  
  /**
   * 创建接收超时消息
   */
  receiveTimeout(): ReceiveTimeout {
    return new ReceiveTimeout();
  },
  
  /**
   * 创建毒丸消息
   */
  poisonPill(): PoisonPill {
    return new PoisonPill();
  }
}; 